package com.game.logic.netty;

import com.game.logic.config.GameServerConfig;
import com.game.logic.service.ActivityService;
import com.game.logic.service.LoginService;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.epoll.Epoll;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.remoting.common.RemotingUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Slf4j
@Component
public class ClientNettyServerBoot {

	@Autowired
	private ApplicationContext applicationContext;
	private NioEventLoopGroup bossGroup = null;
	private NioEventLoopGroup workerGroup = null;
	// 注入网关服务配置
	@Autowired
	private GameServerConfig serverConfig;
	//@Autowired
	//private ClientChannelService clientChannelService;
	@Autowired
	private LoginService loginService;
	@Autowired
	private ActivityService activityService;

	@Resource
	private ClientNettyInitializer clientNettyInitializer;

	@Getter
	private ServerBootstrap serverBootstrap;

	public void startServer() {
		//this.applicationContext = context;
		int port = this.serverConfig.getServerPort();
		try {
			bossGroup = new NioEventLoopGroup(serverConfig.getBossThreadCount());
			workerGroup = new NioEventLoopGroup(serverConfig.getWorkThreadCount());
			this.serverBootstrap = new ServerBootstrap();
			this.serverBootstrap
					.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.childHandler(this.clientNettyInitializer);
			this.serverBootstrap.bind(port);
//			serverBootstrap.group(bossGroup, workerGroup)
//					.channel(NioServerSocketChannel.class)
//					.option(ChannelOption.SO_BACKLOG, 1024).option(ChannelOption.SO_REUSEADDR, true)
//					.option(ChannelOption.SO_KEEPALIVE, false).childOption(ChannelOption.TCP_NODELAY, true)
//					.childOption(ChannelOption.SO_SNDBUF, serverConfig.getSendBufSize())
//					.childOption(ChannelOption.SO_RCVBUF, serverConfig.getRecBufSize())
//					.childOption(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT)
//					.localAddress(new InetSocketAddress(port))
//					.childHandler(createChannelInitializer());
			log.info("开始启动服务，端口:{}", port);
			//ChannelFuture channelFuture = serverBootstrap.bind(port);
			//channelFuture.addListener(new GenericFutureListener<Future<? super Void>>() {
			//	@Override
			//	public void operationComplete(Future<? super Void> future) throws Exception {
			//		log.info("----网关服务器启动成功---");
			//	}
			//});
			//channelFuture.channel().closeFuture().sync();
			//activityService.test();
		} catch (Exception e) {
			log.error("服务器启动失败", e);
			workerGroup.shutdownGracefully();
			bossGroup.shutdownGracefully();
		}
	}

	private boolean useEpoll() {
		return RemotingUtil.isLinuxPlatform() && Epoll.isAvailable();
	}

	// 连接channel初始化的时候调用
//	private ChannelInitializer<Channel> createChannelInitializer() {
//
//		ChannelInitializer<Channel> channelInitializer = new ChannelInitializer<Channel>() {
//			@Override
//			protected void initChannel(Channel ch) throws Exception {
//				ChannelPipeline pipeline = ch.pipeline();
//				try {
//					pipeline.addLast("encoder", new ProtobufEncoder());
//					pipeline.addLast("decoder", new ProtobufDecoder(BaseProto.BaseReq.getDefaultInstance()));
//					pipeline.addLast(new ClientNettyHandler());
//
//					/*
//					pipeline.addLast(new ProtobufVarint32FrameDecoder());
//					pipeline.addLast(new ProtobufDecoder(GatewayMessages.ConfirmRequestParam.getDefaultInstance()));
//					pipeline.addLast(new ProtobufVarint32LengthFieldPrepender());
//					pipeline.addLast(new ProtobufEncoder());
//					pipeline.addLast( new NettyServerHandler());
//
//					int allIdleTimeSeconds = serverConfig.getServerChannelMaxIdleTimeSeconds();
//					pipeline.addLast(new IdleStateHandler(60, 40, allIdleTimeSeconds));
//					//添加拆包
//					pipeline.addLast("LengthFieldBasedFrameDecoder", new LengthFieldBasedFrameDecoder(Integer.MAX_VALUE, 4, 4, 4, 8));
//					pipeline.addLast("ProtobufDecoder", new ProtobufDecoder(GatewayMessages.ConfirmRequestParam.getDefaultInstance()));
//					// 前4个字节记录长度
//					pipeline.addLast("frameEncoder", new LengthFieldPrepender(4));
//					// 添加对象编码器 在服务器对外发送消息的时候自动将实现序列化的Proto对象编码
//					pipeline.addLast("ProtobufEncoder", new ProtobufEncoder());
//					//pipeline.addLast("EncodeHandler", new EncodeHandler());// 添加编码Handler
//					//pipeline.addLast("DecodeHandler", new DecodeHandler());// 添加解码
//					pipeline.addLast("ConfirmHandler", new ConfirmHandler());
//					pipeline.addLast("HeartbeatHandler", new HeartbeatHandler());
//					pipeline.addLast("DispatchGameMessageHandler", new DispatchGameMessageHandler(applicationContext));
//					*/
//
//				} catch (Exception e) {
//					ch.close();
//					log.error("创建channel失败", e);
//				}
//			}
//		};
//		return channelInitializer;
//	}

//	public void shutdownGatewayServer() {
//		int quietPeriod = 5;
//		int timeout = 30;
//		TimeUnit timeUnit = TimeUnit.SECONDS;
//		if (workerGroup != null) {
//			workerGroup.shutdownGracefully(quietPeriod, timeout, timeUnit);
//		}
//		if (bossGroup != null) {
//			bossGroup.shutdownGracefully(quietPeriod, timeout, timeUnit);
//		}
//	}
}
